'''
Created on 2011-6-6

@author: elm
'''
import json,string,pickle
from ddbms.Schema import *
from ddbms.StaticSchema import *
from ddbms.SqlStatement import Condition,Op
from ddbms.RelationalAlgebra import *
from ddbms.Dataset import Dataset

def toJson(obj):
    if (isinstance(obj,Schema)
        or isinstance(obj,ddbms.Schema.Table)
        or isinstance(obj,Segment)
        or isinstance(obj,Site)
        or isinstance(obj,Column)
        or isinstance(obj,HorizontalSegment)
        or isinstance(obj,VerticalSegment)
        or isinstance(obj,Condition)
        or isinstance(obj,TableRef)
        or isinstance(obj,FieldRef)
        or isinstance(obj,RATree)
        or isinstance(obj,Dataset)      
        or isinstance(obj,Op)  
    ):
        ret = {"__class__":obj.__class__.__name__ }
        fields = dir(obj)
        for field in fields:
            if field.startswith("__") and field.endswith("__"):
                continue
            value = getattr(obj,field)
            if callable(value):
                continue
            ret[field] = value
        return ret    
    else:
        raise TypeError(repr(obj) + ' is not JSON serializable')
def dump(obj):
    return json.dumps(obj, default=toJson)
    #return pickle.dumps(obj)

def fromJson(json_object):
    if isinstance(json_object,dict):                            
        if '__class__' in json_object:                            
            g = globals()
            type = json_object["__class__"]
            if type in g:
                obj = g[type]()
                for k in json_object:
                    if k=="__class__":
                        continue
                    if hasattr(obj,k):
                        setattr(obj,k,fromJson(json_object[k]))
                json_object = obj
    if isinstance(json_object,Schema):
        map = json_object.sites
        newmap = {}
        for k in map:
            nk = string.atoi(k)
            newmap[nk]=map[k]
        json_object.sites = newmap
        map = json_object.tables
        newmap = {}
        for k in map:
            nk = string.atoi(k)
            newmap[nk]=map[k]
        json_object.tables = newmap
        map = json_object.columns
        newmap = {}
        for k in map:
            nk = string.atoi(k)
            newmap[nk]=map[k]
        json_object.columns = newmap
        map = json_object.segments
        newmap = {}
        for k in map:
            nk = string.atoi(k)
            newmap[nk]=map[k]
        json_object.segments = newmap
    return json_object

def read(str,type=None):
    if str == None:
        return None
    
    if type==None:
        return json.loads(str, object_hook = fromJson)
    else:
        map = json.loads(str)
        obj = type()
        for k in map:
            if hasattr(obj,k):
                setattr(obj,k,fromJson(map[k]))
        return obj